home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / gopher1.12 / gopherd / daemon.c next >
Encoding:
C/C++ Source or Header  |  1992-12-21  |  4.3 KB  |  187 lines

  1. /********************************************************************
  2.  * $Author: lindner $
  3.  * $Revision: 1.1 $
  4.  * $Date: 1992/12/10 23:13:27 $
  5.  * $Source: /home/mudhoney/GopherSrc/release1.11/gopherd/RCS/daemon.c,v $
  6.  * $Status: $
  7.  *
  8.  * Paul Lindner, University of Minnesota CIS.
  9.  *
  10.  * Copyright 1991, 1992 by the Regents of the University of Minnesota
  11.  * see the file "Copyright" in the distribution for conditions of use.
  12.  *********************************************************************
  13.  * MODULE: daemon.c
  14.  * Routines to detach from and run as a daemon.
  15.  *********************************************************************
  16.  * Revision History:
  17.  * $Log: daemon.c,v $
  18.  * Revision 1.1  1992/12/10  23:13:27  lindner
  19.  * gopher 1.1 release
  20.  *
  21.  *
  22.  *********************************************************************/
  23.  
  24. #include "gopherd.h"
  25.  
  26. #if defined(_AIX)  /** AIX needs bsd signals.  **/
  27. #define _BSD
  28. #endif
  29.  
  30. /*
  31.  * A BSD style SIGCLD signal handler that can be used by a server
  32.  * that's not interested in its child's exit status, but needs to
  33.  * wait for them, to avoid clogging up the system with zombies.
  34.  *
  35.  * Beware that the calling process may get an interrupted system
  36.  * call when we return, so they had better handle that.
  37.  *
  38.  * (From Stevens pg 82)
  39.  */
  40.  
  41. #include "Wait.h"
  42.  
  43. /* some machines don't have SIGCLD defined */
  44. #ifndef SIGCLD
  45. #define SIGCLD        SIGCHLD
  46. #endif
  47.  
  48. #ifdef hpux
  49. #define TIOCNOTTY       _IO('t', 113)           /* void tty association */
  50. #endif
  51.  
  52. void
  53. sig_child()
  54. {
  55.      /*
  56.       * Use the wait3() system call with the WNOHANG option
  57.       */
  58.  
  59.      int pid;
  60.      Portawait status;
  61.  
  62.      while ( (pid = wait3(&status, WNOHANG|WUNTRACED, NULL)) > 0)
  63.       ;
  64. }
  65.  
  66.  
  67. #include <stdio.h>
  68. #include <sys/param.h>
  69. #include <errno.h>
  70. extern int errno;
  71.  
  72. #if defined(SIGTSTP) && !defined(M_XENIX) && !defined(USG)/* True on a BSD system */
  73. #include <sys/file.h>
  74. #include <sys/ioctl.h>
  75. #endif
  76.  
  77. /*
  78.  * Detach a daemon process from login session context
  79.  */
  80.  
  81. void
  82. daemon_start(ignsigcld)
  83.   int ignsigcld;          /* Nonzero -> nuke zombie children */
  84. {
  85.      register int childpid, fd;
  86.  
  87.      /*
  88.       * If we were started by init (process 1) from the /etc/inittab
  89.       * file there's no need to detach.
  90.       */
  91.       
  92.      if (getppid() != 1) {
  93.  
  94.       
  95.  
  96. #ifdef SIGTTOU
  97.       signal(SIGTTOU, SIG_IGN);
  98. #endif
  99. #ifdef SIGTTIN
  100.       signal(SIGTTIN, SIG_IGN);
  101. #endif
  102. #ifdef SIGTSTP
  103.       signal(SIGTSTP, SIG_IGN);
  104. #endif
  105.  
  106.       /*
  107.        * If we were not started in the background, fork and let
  108.        * the parent exit.  This also guarantees the first child
  109.        * is not a process group leader.
  110.        */
  111.  
  112.       if ( (childpid = fork()) < 0)
  113.            err_sys("can't fork first child");
  114.       else if (childpid >0)
  115.            exit(0);     /* parent */
  116.       
  117.       /*
  118.        * First Child process
  119.        *
  120.        * Disassociate from controlling terminal and process group.
  121.        * Ensure the process can't reacquire a new controlling terminal
  122.        */
  123.       
  124. #if defined(SIGTSTP) && !defined(USG)  /* BSD */
  125.       
  126. #if defined(hpux) || defined(_SEQUENT_) || defined(_CRAY) || defined(USG)
  127.       setsid();
  128. #else
  129.       if (setpgrp(0, getpid()) == -1)
  130.            err_sys("can't change process group");
  131.       
  132.       if ( (fd = uopen("/dev/tty", O_RDWR)) >= 0) {
  133.            ioctl(fd, TIOCNOTTY, (char *)NULL); /* lose controlling TTY*/
  134.            close(fd);
  135.       }
  136. #endif /* hpux  et al.*/
  137.       
  138. #else /* System V */
  139.       
  140.       if (setpgrp() == -1)
  141.            err_sys("Can't change process group");
  142.       
  143.       signal(SIGHUP, SIG_IGN);  /* immune from pgrp leader death */
  144.       
  145.       if ( (childpid = fork()) < 0)
  146.            err_sys("Can't fork second child");
  147.       else if (childpid > 0)
  148.            exit(0); /* First child */
  149.       
  150.       /* second child */
  151. #endif
  152.  
  153.      }  /* End of if test for ppid == 1 */
  154.  
  155.      /** Close any file descriptors **/
  156.  
  157.      for (fd = 0; fd < NOFILE; fd++)
  158.       close(fd);
  159.  
  160.      errno = 0;  /* probably set to EBADF from a close */
  161.  
  162.  
  163.      /** Change the current directory to / **/
  164.  
  165.      /* No need for this, since we're already where we want to be */
  166.      /* rchdir("/"); */
  167.  
  168.      /** Clear inherited file mode creation mask. **/
  169.  
  170.      umask(0);
  171.  
  172.      /*
  173.       * See if the caller isn't ineterested in the exit status of its
  174.       * children, and doesn't want to have them become zombies
  175.       */
  176.  
  177.      if (ignsigcld) {
  178. #if defined(SIGCLD) && !defined(_CRAY) && !defined(USG)
  179.       void sig_child();
  180.  
  181.       signal(SIGCLD, sig_child);  /* BSD */
  182. #else
  183.       signal(SIGCLD, SIG_IGN);    /* System V */
  184. #endif
  185.      }
  186. }
  187.